/*
 * WlanService.cpp
 *
 *  Created on: 2023年4月11日
 *      Author: 15271
 */
#include "WlanService.h"
#include "log.h"
#include "ini.h"
#include "mediaPriv.h"

#include <stdio.h>
#include <string.h>
#include <thread>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "ConfigApi.h"
#include <cstdio>
#include "CurtainActManager.h"
#include "ScreenMirrorStream.h"
#include "Pal/Net.h"
#include "Gui/GuiDisplay.h"
#include "Protocol/ProtocolApi.h"



using namespace Protocol;

using namespace ConfigApi;
#define SIGNALSTRENGTH 14

//extern unsigned long long vdo_get_time();
int wifiFlag = 0;//0为未连接，1为连接,2为失败
extern "C" int MEDIA_productWIfiThd(void){
    //开启产测场景
    if(!Media::CurtainActManager::instance()->productTestCurtainPlay()){
        return -1;
    }
    //设置标志位
    wifiFlag = 0;
    //开启线程连接WIFI，线程中根据函数的执行结果改变WIfi的连接状态
    auto lam = [wifiFlag](){
        FILE *fp;
        char ipaddr[32] = {0};
        int num = 0;
        char buff[1024] = {0};
        char cmd[64] = {0};
        char *pStr;
        string gateway;
        bool result = Media::WlanService::instance()->connectWifi("TP-LINK_DE59", "987654321", "");
        warnf("LinkWIfi result ----> %d\n", result);
        if(!result)
        {
            errorf("product test connwifi faild!\n");
            wifiFlag = 2;
            gateway = "";
        }else{
            int index = 0;
            while(Media::WlanService::instance()->getWlanGateway().empty() && index < 20){
                sleep(1);
                index++;
            }
            gateway = Media::WlanService::instance()->getWlanGateway();
        }

        warnf("wifiFlag : %d , gateway:%s\n", wifiFlag, gateway.c_str());

        //这里得增加网络连通性ping包测试，可以参考vm33
        if(!gateway.empty())
        {
            sprintf(cmd, "ping -I wlan0 -c 3 -W 1 %s", gateway.c_str());
            tracef("cmd: %s\n", cmd);
            fp = popen(cmd, "r");
            if (!fp)
            {
                errorf("Fail to popen.\n");
                wifiFlag = 2;
            }else{
                fread(buff, 1, 1024, fp);
                pStr = strstr(buff, "packets transmitted");
                if (pStr)
                {
                    tracef("pStr:%s\n", pStr);
                    sscanf(pStr, "packets transmitted, %d packets received", &num);
                }
                if (num > 0)
                {
                    wifiFlag = 1;
                }
                else
                {
                    wifiFlag = 2;
                }
                pclose(fp);
            }
        }else{
            wifiFlag = 2;
        }


        warnf("wifiFlag : %d , gateway:%s\n", wifiFlag, gateway.c_str());

        //产测调用接口等待wifi连接完毕之后需要销毁配置文件中的wifi连接信息
#if 0
        fp = popen("rm -rf /mnt/mtd/Config /extern/backups/mtd/Config", "r");
		if(!fp){
			errorf("remove old Config Error popen faild\n");
		}else{
			pclose(fp);
		}
#endif
        Json::Value wifiTable;
        wifiTable["SSID"] = "";
        wifiTable["key"]  = "";
        wifiTable["BSSID"] = "";
        wifiTable["Connected"] = false;
        ConfigApi::IConfigInterface::GetInstance()->Set("Wifi", wifiTable, ConfigApi::ConfigOptions::ConfigOptionPart);
    };
    std::thread wifiThd(lam);
    wifiThd.detach();
    return 0;
}

extern "C" int MEDIA_wifiLinkStatus(void){
    //直接返回wifi的连接状态
    warnf("wifiLinkStatus wifiFlag: %d\n", wifiFlag);
    if(wifiFlag == 1){
        return 0;
    }else{
        return 1;
    }
}

extern "C" int MEDIA_wifiSignal(void){
    //这里需要监测wifi的连接状态，如果连接成功才去数据结构中取出，由于wifi最多等待30s所以提默认最多空转30s
    for(int i = 0; i < 30; i++){
        tracef("wifiFlag: -----------> %d\n", wifiFlag);
        if(wifiFlag > 0){
            break;
        }
        sleep(1);
    }
    if(wifiFlag == 1){
        return  Media::WlanService::instance()->getWifiApSignalDb("TP-LINK_DE59");
    }else{
        return 0;
    }
}


extern "C" int MEDIA_setDhcp(int enable){
    if(enable == 1){
        Media::WlanService::instance()->setWiredNetwork("", "", "", true);
    }else{
        Media::WlanService::instance()->setWiredNetwork("", "", "", false);
    }
    return 0;
}

extern "C" int getDispayOsdInfo(char* info)
{	
	//设备名
	std::string name;
	Json::Value nameTable;
	IConfigInterface::GetInstance()->Get("DevName", nameTable);
	if(nameTable.isMember("Name") && nameTable["Name"].isString()){
		name = nameTable["Name"].asString();
	}else{
		name = "";
	}
	//投屏密码
	std::string devicePassword =  Media::ScreenMirrorStream::instance()->getdevicePassword();
	std::string spacePwd;
	for (size_t i = 0; i < devicePassword.length(); i++) {
        spacePwd += devicePassword.substr(i, 1) + "   ";
    }
	//AP名称和密码
	std::string apInfo;
	Media::WlanService::instance()->getApInfo(apInfo);
	
	std::string staSsid;
    Media::WlanService::instance()->getStaInfo(staSsid);
    
    if(staSsid.empty()){
        staSsid = "No connected";
    }

    std::string wiredIp;
    Json::Value table;
    bool result =  Media::WlanService::instance()->getWiredNetwork(table);
    if(mii_diag(LAN_ETH0) == 0 && result){
        wiredIp = "Ethernet : " + table["IP"].asString();
    }else{
        wiredIp = "Ethernet : No connected";
    }

	std::string infoStr = name + "%" + spacePwd + 
            "%" + apInfo + "%Wi-Fi: " + staSsid + "%" + wiredIp + "%";
	
    if(!Media::ScreenMirrorStream::instance()->isActived()){
        infoStr += (std::string)"inactivated" + "%";
    } 

	memcpy(info, infoStr.c_str(), infoStr.size());
	return 0;
}


static unsigned long long airplayFirstTime = 0;
static unsigned long long usbdisplayFirstTime = 0;

extern "C" int showOsdInfo()
{	
	//获取配置文件中的标志位
	Json::Value osdTable;
	bool osdMark;
	unsigned long long waitTime  = 10000;
	IConfigInterface::GetInstance()->Get("VideoShowOSD", osdTable);
	if(osdTable.isMember("ScreenMirror") && osdTable["ScreenMirror"].isBool()){
		osdMark = osdTable["ScreenMirror"].asBool();
	}else{
		osdMark = false;
	}

	//打开直接显示不处理
	if(osdMark){
		return 0;
	}


	//获取标志位
	bool airplayConn = Media::ScreenMirrorStream::instance()->getAirplayConnect();
	bool usbdisplayConn = Media::ScreenMirrorStream::instance()->getUsbDisplayConnect();

	//这里的思路应该是获取标志位，对于时间超过5S的标志位进行过滤，对于私有协议和airplay的分别判断只要有一个在投就需要显示
	if(airplayConn == true){
		if(airplayFirstTime == 0){
			airplayFirstTime = vdo_get_time();
			return 0;
		}else{
			if(vdo_get_time() - airplayFirstTime > waitTime){
				Media::ScreenMirrorStream::instance()->setAirplayConnect(false);
				return -2;
			}else{
				return 0;
			}
		}
	}else{
		if(airplayFirstTime != 0){
			airplayFirstTime = 0;
		}
	}

	if(usbdisplayConn == true){
		if(usbdisplayFirstTime == 0){
			usbdisplayFirstTime = vdo_get_time();
			return 0;
		}else{
			
			if(vdo_get_time() - usbdisplayFirstTime > waitTime){
				Media::ScreenMirrorStream::instance()->setUsbDisplayConnect(false);
				return -2;
			}else{
				return 0;
			}
		}
	}else{
		if(usbdisplayFirstTime != 0){
			usbdisplayFirstTime = 0;
		}
	}

	return -3;
}

namespace Media{
    WlanService *WlanService::sm_WlanService = nullptr;
    mutex WlanService::sm_WlanMutex;

    WlanService *WlanService::instance(){
        lock_guard<mutex> instance_lock(sm_WlanMutex);
        if(sm_WlanService == nullptr){
            sm_WlanService = new WlanService();
        }
        return sm_WlanService;
    }

    WlanService::WlanService(){
        m_initFlag = initWlan();
        m_ap_mutex_mark = false;
        m_ap_channel = -1;
        m_wifi_channel = -1;
        m_sta_mutex_mark = false;

        //确保初始化时当前连接的WIFI状态时对的，避免上一次关机之后设置了状态时已连接重新开机获取到错误的状态
        Json::Value wifiTable;
        wifiTable["Connected"] = false;
        IConfigInterface::GetInstance()->Set(wifiPath, wifiTable, ConfigOptions::ConfigOptionPart);


        //读取WIFI连接的参数，确保首次WIFI连接失败时能够多次重连
        Json::Value wifiInfo;
        IConfigInterface::GetInstance()->Get(wifiPath, wifiInfo);
        m_curSsid = wifiInfo["SSID"].asString();
        m_curKeys = wifiInfo["key"].asString();
        m_curBssid = wifiInfo["BSSID"].asString();
    }

    WlanService::~WlanService(){
        m_initFlag = false;
        WLanClose();
        m_netStateThread.stop();
    }

    bool WlanService::startDynamicRouteService()
    {
        return m_netStateThread.start([this](Fdt::Thread *thread){this->NetThreadProc(thread);}); //启动单独线程处理路由
    }

    bool WlanService::initWlan(){
        //开启WiFi服务
        int ret = WLanInit();
        if (ret)
        {
            errorf("wlan init failed!\n");
            return false;
        }
        //打开WIFI
        if(WLanOpen() != 0){
            errorf("WLanOpen faild !!\n");
            return false;
        }
        //获取当前WIFI支持的能力
        WLAN_CAPS relay;
        ret = WLAN_GetCaps(&relay);
        if (ret)
        {
            warnf("wlan relay capacity get faild!\n");
        }
        else
        {
            if (relay.relayEnable)
            {
                tracef("wlan support relay!\n");
            }
            else
            {
                //tracef("wlan not support relay!\n");
            }

        }
        //查看当前WIFI模块是否可用
        ret = WLanCheckModule();
        if (!ret)
        {
            warnf("wlan relay capacity get faild!\n");
            return false;
        }

        return true;
    }

    bool WlanService::getStaInfo(std::string &ssid){
        //可能会有线程安全问题
        if(m_wifiConStatus){
            ssid = m_curSsid;
            return true;
        }else{
            ssid.clear();
            return false;
        }
    }

    bool WlanService::disConnWifi(){
        lock_guard<recursive_mutex> connLock(m_connMutex);
        warnf("------------------------------------disConnWifi\n");
        CONFIG_WLAN_EXT config;
        memset(&config, 0, sizeof(CONFIG_WLAN_EXT));
        //判断当前WLan是否初始化完成
        if(!m_initFlag){
            errorf("initWlan Service faild\n");
            return false;
        }
        //断开当前连接
        config.Enable = 0;
        int ret = WLanSetConfigExt(&config);
        if (ret)
        {
            errorf("WLanSetConfigExt failed!\n");
            return false;
        }

        return true;
    }

    void WlanService::wifiConnectCheck(){
        //开线程实时监听WIFI的连接状态，断开重连
        if(!m_sta_mutex_mark)
        {
            m_sta_mutex_mark = true;
            auto lam = [this]()
            {
                int checkDisconnectCount = 0;
                int maxDisconnectCount = 30;
                while(1)
                {
                    if(!m_wifiConStatus || !getWirelessStatus()){
                        checkDisconnectCount++;
                        if(!m_curSsid.empty() && !m_curKeys.empty()){
                            do{
                                auto disConnectWifiLam = [this](){
                                    if(m_wifiConStatus){
                                        disConnWifi();
                                        //退出dhcp 线程
                                        if(m_WlanThreadMark){
                                            m_WlanThreadMark = false;
                                            while(!m_WlanThreadExit){
                                                usleep(10 * 1000);
                                            }
                                        }
                                    }

                                    m_wifiConStatus = false;
                                };

                                if(checkDisconnectCount < maxDisconnectCount){
                                    disConnectWifiLam();
                                    break;
                                }

                                checkDisconnectCount = 0;
                                if(!Media::ScreenMirrorStream::instance()->getShareScreenStatus() ||
                                    MirrorNetcard() == LAN_WLAN0){
                                    disConnectWifiLam();
                                    connectWifi(m_curSsid, m_curKeys, m_curBssid);
                                }
                            }while(false);
                        }else{
                            m_wifiConStatus = false;
                            checkDisconnectCount = 0;
                        }
                    }else{
                        checkDisconnectCount = 0;
                    }
                    std::this_thread::sleep_for(std::chrono::seconds(1));
                }
            };
            thread checkwifi(lam);
            checkwifi.detach();
        }
    }

    bool WlanService::connectWifi(string ssid, string key, string bssid, int time_sec){
        
        if(Media::ScreenMirrorStream::instance()->getShareScreenStatus() && !ssid.empty())
        {
            errorf("The device is displaying screen mirroring information\n");
            return false;
        }
    
        lock_guard<recursive_mutex> connLock(m_connMutex);

        CONFIG_WLAN_EXT config;
        memset(&config, 0, sizeof(CONFIG_WLAN_EXT));
        //判断当前WLan是否初始化完成
        if(!m_initFlag){
            errorf("initWlan Service faild\n");
            return false;
        }

        if(ssid.empty()){
            //第一次开启AP
            if(m_ap_channel == -1){ 
                openApService("", "", -1, "");
            }

            if(!m_sta_mutex_mark || m_curSsid == ""){
                return true;
            }

            stopMirrorWeaknetDetect();
            GuiDisplay::Instance()->CloseDisplayWarnWifi();
            //线程停止重连
            m_curSsid = "";
            m_curKeys = "";

            //断开当前连接
            config.Enable = 0;
            int ret = WLanSetConfigExt(&config);
            if (ret)
            {
                errorf("WLanSetConfigExt failed!\n");
                return false;
            }

            Json::Value wifiTable;
            wifiTable["SSID"] = "";
            wifiTable["key"]  = "";
            wifiTable["BSSID"] = "";
            wifiTable["Connected"] = false;
            IConfigInterface::GetInstance()->Set(wifiPath, wifiTable, ConfigOptions::ConfigOptionPart);

            //退出dhcp 线程
            if(m_WlanThreadMark){
                m_WlanThreadMark = false;
                while(!m_WlanThreadExit){
                    usleep(10 * 1000);
                }
            }
            m_wifiConStatus = false;
            warnf("ssid is empty disconnect wifi\n");
            //重新打开AP，选择最好的信道
            if(m_ap_channel != -1){ 
                openApService("", "", -1, "");
            }
            return true;
        }

        //防止多次连接一个WIFI
        if(ssid == m_curSsid && key == m_curKeys && m_wifiConStatus){
            errorf("ssid:%s is already connnect\n", ssid.c_str());
            return true;
        }

        warnf("connectWifi start ssid:%s, key=%s, bssid:%s\n", ssid.c_str(), key.c_str(), bssid.c_str());

        char IPADDR[32] = {0};
        char NETMASK[32] = {0};
        char GATEWAY[32] = {0};
        char Destination[32] = {0};

        //每次连接开始的时候都清空当前连接的WIfi，并且重置网络
        // stopMirrorWeaknetDetect();
        // GuiDisplay::Instance()->CloseDisplayWarnWifi();

        Json::Value wifiTable;
        wifiTable["Connected"] = false;
        IConfigInterface::GetInstance()->Set(wifiPath, wifiTable, ConfigOptions::ConfigOptionPart);

        int connectNumber = 0;

        //连接WIFI
        config.Enable = 1;
        strcpy(config.SSID, ssid.c_str());
        strcpy(config.Keys, key.c_str());
        config.Encryption = 5;

        if(!bssid.empty()){
            strcpy(config.BSSID, bssid.c_str());
        }

        int ret = WLanSetConfigExt(&config);
        if (ret == 0)
        {
            string wifi_bssid;
            string wifi_ssid;
            unsigned int wifi_channel = 0;
            while(!getWirelessStatus(wifi_bssid, wifi_ssid, wifi_channel) && connectNumber < time_sec){
                connectNumber++;
                std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            }
            
            if(connectNumber >= time_sec){
                errorf("cannot connect the Access Point:%s\n", ssid.c_str());
                disConnWifi();
                m_wifiConStatus = false;
            }else{
                if(bssid.empty()) bssid = wifi_bssid;
                m_wifi_channel = wifi_channel;
                m_wifiConStatus = true;
            }
        }

        //第一次开启AP
        if(m_ap_channel == -1){ 
            openApService("", "", -1, "");
        }

        if(ret || connectNumber >= time_sec){
            errorf("connect failed!\n");
            wifiConnectCheck();
            return false;
        }

        wifiTable["SSID"] = ssid;
        wifiTable["key"]  = key;
        wifiTable["BSSID"] = bssid;
        wifiTable["Connected"] = true;
        IConfigInterface::GetInstance()->Set(wifiPath, wifiTable, ConfigOptions::ConfigOptionPart);

        //保存成功连接信息
        m_curSsid = ssid;
        m_curKeys = key;
        m_curBssid = bssid;

        //首先需要确保旧的线程关闭
        if(m_WlanThreadMark){
            m_WlanThreadMark = false;
            while(!m_WlanThreadExit){
                usleep(10 * 1000);
            }
        }
        m_WlanThreadExit = false;
        m_WlanThreadMark = true;
        //开启对应的线程去处理
        m_WlanThread = std::thread(&WlanService::dhcpcThreadFuc, this, LAN_WLAN0);
        m_WlanThread.detach();

        warnf("connectWifi success\n");

        //ap信道与wifi信道不一致，重启AP
        if(m_ap_channel != m_wifi_channel){
            if(Media::ScreenMirrorStream::instance()->getShareScreenStatus()){
                m_wifiConStatus = false;
                disConnWifi();
            }else{
                openApService("", "", -1, "");
            }
        }
        
        wifiConnectCheck();
        return true;
    }


    bool WlanService::wlanTranspond()
    {
        lock_guard<mutex> guard(m_transSetMutex);
        //获取当前默认路由的网卡
        WlanDelNatForward();
        RouteUtil routeManage;
        vector<RouteItem> defRouteTable;
        bool result = routeManage.GetRouteTabel("default", defRouteTable);
        if(!result)
        {
            errorf("GetRouteTabel default failed\n");
            return false;
        }
        //转发到获取默认路由的网卡
        tracef("curdefult network card: %s\n", defRouteTable[0].ethName.c_str());

        WlanSetNatForward(defRouteTable[0].ethName.c_str());

        tracef("wlanTranspond end...\n");
        return true;
    }

    bool WlanService::openApService(string Password, string FreqBand, int Retransmit, string ssid){
        warnf("openApService ssid:%s Password:%s, FreqBand:%s, start\n", ssid.c_str(), Password.c_str(), FreqBand.c_str());
        lock_guard<mutex> apService(m_openApLock);
        if(!m_initFlag){
            errorf("initWlan Service faild\n");
            return false;
        }
        if(!Password.empty() && Password.length() < 8){
            errorf("Password error\n");
            return false;
        }

        //关闭ap
        // system("hostapd_cli -i wlan1 DISABLE");

        WLAN_AP_CFG wlanApCfg;

        memset(&wlanApCfg, 0, sizeof(WLAN_AP_CFG));

        //使用和赋值需要分开

        unsigned int channel = getApChannels();
        warnf("openApService  getApChannels   %d", channel);

		if(channel == 0){
			errorf("faild to getWifi\n");
			return false;
		}
		wlanApCfg.Channel      = channel;
		wlanApCfg.AuthMode     = 5;
		wlanApCfg.EncrypType   = 5;
		wlanApCfg.WirelessMode = 9;

		Json::Value apTable;
		string apPath = "APInfo";
		IConfigInterface::GetInstance()->Get(apPath, apTable);
		//warnf("nameTbale:%s\n", nameTable.toStyledString().c_str());
		//warnf("apTbale:%s\n", apTable.toStyledString().c_str());
		
		#if defined(MODEL_ROOMS) 
			string apName = "NearHub-ROOMS-";
		#else defined(MODEL_AIR)
			string apName = "NearHub-AIR-";
		#endif
		
		char snid[64] = {0};
        int status_get_snid = INI_KeyGetString(DEV_HARDWARE_PATH, "hardwareTest", "snid", snid);
        if(status_get_snid < 0){
            errorf("openService get snid fail\n");
            return false;
        }
        string sn = snid;
        apName = apName + sn.substr(sn.size() - 6, 6);
        //获取频段，密码，是否转发
        if(!apTable.isMember("Password") || !apTable.isMember("FreqBand") || !apTable.isMember("Retransmit")){
            errorf("cannot find wifi from config");
            return false;
        }
        string setPassword = apTable["Password"].asString();
        string setFreqBand = apTable["FreqBand"].asString();
        int    setRetransmit  =  apTable["Retransmit"].asInt();
        //如果默认传入了参数就覆盖，没有传入就使用读取的结果
        if(!Password.empty()){
            setPassword = Password;
        }
        if(!FreqBand.empty()){
            setFreqBand = FreqBand;
        }
        if(Retransmit >= 0){
            setRetransmit = Retransmit;
        }
        if(!ssid.empty()){
            apName = ssid;
        }

        ///确保wlan1的IP地址与其他两个网卡不冲突
        std::string eth0Addr;
        std::string wlan0Addr;
        std::string wlan1Addr;
        GetInterfaceWishaddr(LAN_ETH0, 0, eth0Addr);
        GetInterfaceWishaddr(LAN_WLAN0, 0, wlan0Addr);
        for(int i = 0; i < 3; ++i)
        {
            if(apWlanAddr[i] != eth0Addr
               && apWlanAddr[i] != wlan0Addr)
            {   
                int apAddr[4] = {0};
                sscanf(apWlanAddr[i].c_str(), "%d.%d.%d.%d", &apAddr[0], &apAddr[1], &apAddr[2], &apAddr[3]);
                apAddr[3] = 1;
                sprintf(apWlanAddr[i].c_str(), "%d.%d.%d.%d", apAddr[0], apAddr[1], apAddr[2], apAddr[3]);
                wlan1Addr = apWlanAddr[i];
                break;
            }
        }

        //tracef("setPassword:%s  setFreqBand:%s    setRetransmit:%d  apName:%s", setPassword.c_str(), setFreqBand.c_str(), setRetransmit, apName.c_str() );
        strcpy(wlanApCfg.ssid, apName.c_str());
        strcpy(wlanApCfg.key, setPassword.c_str());
        strcpy(wlanApCfg.Ifname, "wlan1");
        strcpy(wlanApCfg.IpAddr, wlan1Addr.c_str());
        strcpy(wlanApCfg.NetMask, "255.255.255.0");

        if(WlanSetApCfg(&wlanApCfg) == -1){
            errorf("open wifiAP faild!\n");
            return false;
        }
        m_ap_channel = channel;

		m_apInfo = "AP: " + apName + "%" + "Password: " + setPassword;

        m_apName = apName;
        m_apPassword = setPassword;
	
    	///设置udhchc的分配范围
		std::string startAddr;
		std::string stopAddr;
        GetInterfaceWishaddr(LAN_WLAN1, 1, wlan1Addr);
        GetInterfaceWishaddr(LAN_WLAN1, 151, startAddr);
        GetInterfaceWishaddr(LAN_WLAN1, 161, stopAddr);

        if(WlanStartDhcpd("wlan1", wlan1Addr.c_str(), startAddr.c_str(), stopAddr.c_str()) == -1){
            errorf("open wifiAP WlanStartDhcpd faild!\n");
            //to do ?
        }

        apTable["FreqBand"] = setFreqBand;
        apTable["Password"] = setPassword;
        apTable["Retransmit"] = setRetransmit;
        apTable["Ssid"] = apName;


        bool ret = IConfigInterface::GetInstance()->Set(apPath, apTable, ConfigOptions::ConfigOptionPart);
        warnf("openApServic succeed   end\n");
        return ret;
    }

    bool WlanService::chooseAp(WLAN_DEVICE_EXT *opt1, WLAN_DEVICE_EXT *opt2, WLAN_DEVICE_EXT *obj){
        WLAN_DEVICE_EXT *choose;
        if((opt1->Channel > SIGNALSTRENGTH && opt2->Channel > SIGNALSTRENGTH) || (opt1->Channel <= SIGNALSTRENGTH && opt2->Channel <= SIGNALSTRENGTH)){
            //两个都是5G或者两个都是2.4G，选信号强度比较强的一个
            if(opt1->LinkQuality >= opt2->LinkQuality){
                choose = opt1;
            }else{
                choose = opt2;
            }
        }else{
            //如果其中一个2.4G一个5G；对比信号强度。有相差15的就直接选择，否则优先选择5G
            if(opt1->LinkQuality - opt2->LinkQuality >= 15){
                choose = opt1;
            }else if(opt2->LinkQuality - opt1->LinkQuality >= 15){
                choose = opt2;
            }else{
                if(opt1->Channel > SIGNALSTRENGTH){
                    choose = opt1;
                }else{
                    choose = opt2;
                }
            }
        }
        memcpy(obj, choose, sizeof(WLAN_DEVICE_EXT));
        return true;
    }



    //这里需要写一个过滤函数过滤调SSID为空的条目，并且同名的条目只保留一条（优先选择5G，信号强度2.4G比5G大15选择2.4G）
    bool WlanService::apFilter(WLAN_DEVICE_EXT *pApList, unsigned int apnum){
        m_bssidInfo.clear();
        map<string, WLAN_DEVICE_EXT>::iterator apIt;
        //遍历所有的条目放入到map
        for(unsigned int i = 0; i < apnum; i++, pApList++){
            //tracef("scan ssid:%s\n", pApList->SSID);
            //首先丢弃名字为空的条目
            if(strlen(pApList->SSID) == 0){
                //warnf("pApList->SSID is NULL\n");
                continue;
            }
            //查询map中是否已经存在该条目
            apIt = m_bssidInfo.find(pApList->SSID);
            if(apIt != m_bssidInfo.end()){
                //如果存在就按照优先选择5G，信号强度2.4G比5G大15选择2.4G（按照信道的大小来区分2.4和5.信道大于14的是5G）的原则筛选出适合的
                WLAN_DEVICE_EXT *obj = NULL;
                obj = (WLAN_DEVICE_EXT *)malloc(sizeof(WLAN_DEVICE_EXT));
                if(obj == NULL){
                    errorf("malloc faild!!!");
                    return false;
                }
                chooseAp(&(m_bssidInfo[pApList->SSID]), pApList, obj);
                m_bssidInfo[pApList->SSID] = *obj;
                free(obj);
            }else{
                //直接放入到map中,这里是否会存在内存被释放导致野指针？
                m_bssidInfo[pApList->SSID] = *pApList;
            }
        }
        return true;
    }

    //获取当前STA可连接的AP的对应信息
    bool WlanService::scanAP(Json::Value &apList){

        if(Media::ScreenMirrorStream::instance()->getShareScreenStatus())
        {
            errorf("The device is displaying screen mirroring information\n");
            return false;
        }
        
        lock_guard<mutex> scanApLock(m_scanApLock);
        if(!m_initFlag){
            errorf("initWlan Service faild\n");
            return false;
        }

        unsigned int apNum = 0;
        WLAN_DEVICE_EXT *pApList = NULL;
        pApList = (WLAN_DEVICE_EXT *)calloc(150 , sizeof(WLAN_DEVICE_EXT));
        if (!pApList)
        {
            errorf("scanAPs Service faild\n");
            return false;
        }

        WLAN_DEVICE_EXT *pTmp = pApList;

        int ret = WLanScanAPs(pApList, &apNum);
        if (ret < 0)
        {
            errorf("scanAPs Service faild\n");
            goto exit;
        }


        tracef("scanAp num:%d\n", apNum);
        if(!apFilter(pApList, apNum)){
            errorf("Filter ap table faild\n");
            goto exit;
        }

        Json::Value wifiConfig;
        IConfigInterface::GetInstance()->Get(wifiPath, wifiConfig);

        for (auto it = m_bssidInfo.begin(); it != m_bssidInfo.end(); ++it) {
            Json::Value ApMember;
            ApMember["ssid"] = it->second.SSID;
            ApMember["LinkQuality"] = it->second.LinkQuality;
            if(it->second.AuthMode == '0'){
                ApMember["enableAuth"] = false;
            }else{
                ApMember["enableAuth"] = true;
            }
            //判断当前正在连接的Wifi
            if(wifiConfig["SSID"].asString() ==  ApMember["ssid"].asString() && wifiConfig["Connected"].asBool()){
                ApMember["curConnect"] = true;
            }else{
                ApMember["curConnect"] = false;
            }
            apList["apList"].append(ApMember);
        }

  
        // 获取数组的大小
        size_t apListSize = apList["apList"].size();
        // 使用基于索引的方式对 JSON 数组进行排序
        for (size_t i = 0; i < apListSize; ++i) {
            for (size_t j = i + 1; j < apListSize; ++j) {
                if (apList["apList"][i]["LinkQuality"].asInt() < apList["apList"][j]["LinkQuality"].asInt()) {
                    std::swap(apList["apList"][i], apList["apList"][j]);
                }
            }
        }
    exit:
        if(pTmp)
            free(pTmp);
        return true;
    }

    unsigned int WlanService::getApChannels(void)
    {
        lock_guard<mutex> channelLock(m_channelLock);
        string bssid;
        string ssid;
        unsigned int channel;

        if(m_wifiConStatus){
            //已连接返回真实连接的通道
            return m_wifi_channel;
        }

        ///未连接返回最佳合法通道
    	unsigned int apNum = 0;
		std::map<int, int> channelMap;
		int useValue = 1000;
		unsigned int useChannel = apChannel_5180HZ;
        WLAN_DEVICE_EXT *pApList = NULL;
        pApList = (WLAN_DEVICE_EXT *)calloc(150 , sizeof(WLAN_DEVICE_EXT));
        if (!pApList)
        {
            errorf("scanAPs Service faild\n");
            return 0;
        }

		/* start scan env wifi */
        WLAN_DEVICE_EXT *pApListTmp = pApList;
        int ret = WLanScanAPs(pApList, &apNum);
        if (ret < 0)
        {
            errorf("scanAPs Service faild\n");
            return 0;
        }

		/* init map key value */
        channelMap[apChannel_5745HZ] = 0;
        channelMap[apChannel_5785HZ] = 0;
        channelMap[apChannel_5765HZ] = 0;
        channelMap[apChannel_5805HZ] = 0;
        channelMap[apChannel_165] = 0;

        channelMap[apChannel_5200HZ] = 0;
        channelMap[apChannel_5240HZ] = 0;
        channelMap[apChannel_5180HZ] = 0;
        channelMap[apChannel_5220HZ] = 0;


        // channelMap[apChannel_52] = 0;
        // channelMap[apChannel_56] = 0;
        // channelMap[apChannel_60] = 0;
        // channelMap[apChannel_64] = 0;

		for(int i = 0; i < apNum; i++, pApList++)
		{
			if(pApList->Channel < 14)
			{
				continue;
			}

            debugf("ap ssid %s,  LinkQuality %d, channel %d", pApList->SSID, 
                pApList->LinkQuality, pApList->Channel);
			for (const auto& [ch, value] : channelMap)
			{
				if(ch == pApList->Channel){
                    if(pApList->LinkQuality > 40) channelMap[ch]++;
                    break;
                }
    		}
        }

		/* select first min value */
		for (const auto& [ch, value] : channelMap) 
		{
			if(useValue > value)
			{
				useChannel = ch;
				useValue = value;
			}
			
			tracef("channel %d value %d \n", ch, value);
    	}

		tracef("end usechannel %d usevalue %d \n", useChannel, useValue);
		
        if(pApListTmp)
            free(pApListTmp);
		
        return useChannel;
    }

    bool WlanService::JudgeIp(char *szIP,IP_Struct::IpAdress_Struct *ipAdress)
    {
        if (!szIP) return false;
        int index=0;
        int first=0,second=0,third=0,forth=0;
        std::string ip=std::string(szIP);
        first=atoi(&ip[index]);
        if (first>255)
            return false;
        if (ipAdress)
            ipAdress->first=first;

        index++;
        index=ip.find_first_of('.',index);
        second=atoi(&ip[++index]);
        if(second>255)
            return false;
        if (ipAdress)
            ipAdress->second=second;

        index++;
        index=ip.find_first_of('.',index);
        third=atoi(&ip[++index]);
        if(third>255)
            return false;
        if (ipAdress)
            ipAdress->third=third;

        index++;
        index=ip.find_first_of('.',index);
        forth=atoi(&ip[++index]);
        if(forth>255)
            return false;
        if (ipAdress)
            ipAdress->forth=forth;

        return true;
    }

    bool WlanService::IsSameNetworkSegment(char *szIPAdress,char *szMask,char *szIPAdresss1, char *szMask1)
    {
        if (!szIPAdress || !szMask || !szIPAdresss1 || !szMask1
            || (strcmp(szMask, szMask1) != 0))
        {
            return false;
        }

        IP_Struct::IpAdress_Struct ip,ip1,mask;
        if (JudgeIp(szIPAdress,&ip)&&JudgeIp(szIPAdresss1,&ip1)&&JudgeIp(szMask,&mask))
        {
            ip.first=ip.first & mask.first;
            ip.second=ip.second & mask.second;
            ip.third=ip.third & mask.third;
            ip.forth=ip.forth & mask.forth;

            ip1.first=ip1.first & mask.first;
            ip1.second=ip1.second & mask.second;
            ip1.third=ip1.third & mask.third;
            ip1.forth=ip1.forth & mask.forth;

            if(ip.first==ip1.first&&ip.second==ip1.second&&ip.third==ip1.third&&ip.forth==ip1.forth)
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }
    }



    bool WlanService::setDefaultRoute(string netCard)
    {
        vector<RouteItem> routeTable;
        RouteItem routeInfo;
        bool result = false;
        bool addDefFlg = true;
        string gateway;

        string nexthop_test =  "192.168.16.1";

        //1.1 获取当前默认路由
        routeTable.clear();
        result = m_routeManager.GetRouteTabel("default", routeTable);
        if(!result)
        {
            errorf("GetRouteTabel default failed\n");
            return false;
        }

        //1.2 判定用户指定网卡默认路由是否存在
        for (auto it = routeTable.cbegin(); it != routeTable.cend(); ++it)
        {
            if((*it).ethName == netCard)
            {
                addDefFlg = false;
            }
        }

        //1.3 设置用户指定网卡为默认路由
        if(addDefFlg)
        {
            routeInfo.ethName = netCard;
            routeInfo.dest_ip = "0.0.0.0";
            routeInfo.mask = "0.0.0.0";

            //获取用户指定网卡的网关
            if(netCard == LAN_WLAN0)
            {
                gateway = m_wlanGateway;
            }
            else if(netCard == LAN_ETH0)
            {
                gateway = m_wiredGateway;
            }
            routeInfo.nexthop = gateway;

            result = m_routeManager.AddRouteItem(routeInfo, 1);
            if(!result)
            {
                errorf("AddRouteItem failed\n");
                return false;
            }
        }

        //1.4 删除不需要的默认路由
        for (auto it = routeTable.cbegin(); it != routeTable.cend(); ++it)
        {
            if((*it).ethName != netCard)
            {
                result = m_routeManager.DelRouteItem(*it);
                if(!result)
                {
                    errorf("DelRouteItem failed\n");
                    return false;
                }
            }
        }

        return true;
    }

    bool WlanService::setOrdinaryRoute(int ethConnStat, int wlanConnStat)
    {
        vector<RouteItem> routeTable;
        RouteItem routeInfo;
        bool addEthFlg = true;
        bool addWalnFlg = true;

        char ethIp[32] = {0};
        char ethNetmask[32] = {0};
        char wlanIp[32] = {0};
        char wlanNetmask[32] = {0};
        int netLen = 32;

        bool result = false;
        int iRet = 0;
        string delNetcard;
        int wlanMetric = 0;

        //1.1 获取当前eth0和wlan0的ip和子网掩码,普通路由
        iRet = NetGetHostIPEx(LAN_ETH0, ethIp, netLen, ethNetmask, netLen);
        if(iRet && ethConnStat == 0)
        {
            errorf("NetGetHostIPEx failed\n");
            return false;
        }
        printf("NetGetHostIPEx eth0 ip = %s, netmask=%s\n", ethIp, ethNetmask);

        iRet = NetGetHostIPEx(LAN_WLAN0, wlanIp, netLen, wlanNetmask, netLen);
        if(iRet && wlanConnStat == 0)
        {
            errorf("NetGetHostIPEx failed\n");
            return false;
        }
        printf("NetGetHostIPEx wlan0 ip = %s, netmask=%s\n", wlanIp, wlanNetmask);


        //1.2 获取当前eth0和wlan0的普通路由
        addEthFlg = true;
        routeTable.clear();
        result = m_routeManager.GetRouteTabel(LAN_ETH0, routeTable);
        if(!result)
        {
            errorf("GetRouteTabel eth0 failed\n");
            //return false;
        }
        for (auto it = routeTable.cbegin(); it != routeTable.cend(); ++it)
        {
            if((*it).ethName == LAN_ETH0)
            {
                addEthFlg = false;
            }
        }

        addWalnFlg = true;
        routeTable.clear();
        result = m_routeManager.GetRouteTabel(LAN_WLAN0, routeTable);
        if(!result)
        {
            errorf("GetRouteTabel wlan0 failed\n");
            //return false;
        }
        for (auto it = routeTable.cbegin(); it != routeTable.cend(); ++it)
        {
            if((*it).ethName == LAN_WLAN0)
            {
                addWalnFlg = false;
            }
        }

        //1.3 判定路由策略
        delNetcard.clear();
        if(ethConnStat == 0 && wlanConnStat == 0)
        {
            //判断eth0和wlan0是否在同一网段
            if(IsSameNetworkSegment(ethIp, ethNetmask, wlanIp, wlanNetmask))
            {
                //网段相同，eth0普通路由优先级高
                addWalnFlg = false;
                delNetcard = LAN_WLAN0;

                wlanMetric = WLAN0ROUTEMETRIC;
            }
            else
            {
                //网段不同，保留或设置eth0和wlan0普通路由
            }
        }
        else  if(ethConnStat == 0 && wlanConnStat != 0)
        {
            //只保留或设置eth0普通路由
            addWalnFlg = false;
            delNetcard = LAN_WLAN0;
        }
        else  if(ethConnStat != 0 && wlanConnStat == 0)
        {
            //只保留或设置wlan0普通路由
            addEthFlg = false;
            delNetcard = LAN_ETH0;
        }

        //1.4 若缺普通路由，则添加普通路由
        if(addEthFlg)
        {
            routeInfo.ethName = LAN_ETH0;
            routeInfo.dest_ip = m_wiredDest;
            routeInfo.mask = m_wiredNetmask;
            routeInfo.nexthop = "0.0.0.0";

            result = m_routeManager.AddRouteItem(routeInfo, 0);
            if(!result)
            {
                errorf("AddRouteItem failed\n");
                //return false;
            }
        }

        if(addWalnFlg)
        {
            routeInfo.ethName = LAN_WLAN0;
            routeInfo.dest_ip = m_wlanDest;
            routeInfo.mask = m_wlanNetmask;
            routeInfo.nexthop = "0.0.0.0";

            result = m_routeManager.AddRouteItem(routeInfo, 0, wlanMetric);
            if(!result)
            {
                errorf("AddRouteItem failed\n");
                return false;
            }
        }

        //1.6 设置wlan普通路由的优先级
        if(wlanMetric > 1)
        {
            routeInfo.ethName = LAN_WLAN0;
            routeInfo.dest_ip = m_wlanDest;
            routeInfo.mask = m_wlanNetmask;
            routeInfo.nexthop = "0.0.0.0";

            result = m_routeManager.AddRouteItem(routeInfo, 0, wlanMetric);
            if(!result)
            {
                errorf("AddRouteItem failed\n");
                return false;
            }
        }

        //1.5 删除的不需要的普通路由
        if(delNetcard.size() > 0)
        {
            tracef("delNetcard=%s \n", delNetcard.c_str());
            routeTable.clear();
            result = m_routeManager.GetRouteTabel(delNetcard, routeTable);
            if(!result)
            {
                errorf("GetRouteTabel wlan0 failed\n");
                return false;
            }
            for (auto it = routeTable.cbegin(); it != routeTable.cend(); ++it)
            {

                if(wlanConnStat == 0){
                    if((*it).metric == 0)
                    {
                        m_routeManager.DelRouteItem(*it);
                    }
                }else{
                    m_routeManager.DelRouteItem(*it);
                }
                
            }
        }

     

        return true;
    }

    bool WlanService::CheckNetwork(const std::vector<std::string>& httpDst) {
        for (int i = 0; i < httpDst.size(); i++) {
            if(!m_ExtranetThreadRuning.load()){
                break;
            }
        
            Fdt::ErrCode errCode = Fdt::Err_other;
            auto resultCb = [&errCode](const Fdt::SockException &ex, const std::string& response) {
                // if (ex) {
                //     // 请求失败处理
                //     std::cerr << "network err:" << ex.getErrCode() << " " << ex.what() << std::endl;
                // } else {
                //     // 请求成功处理
                //     std::cerr << "succeed" << ex.what() << std::endl;
                // }
                  
                if(ex.getErrCode() == Fdt::Err_other){
                    errCode = Fdt::Err_timeout;
                }else{
                    errCode = ex.getErrCode();
                }
            };
            
            // 在发送 HTTP 请求时，确保 resultCb 对所有变量的引用有效
            Protocol::IProtocolInterface::GetInstance()->SendHttpRequest(httpDst[i], "GET", "", resultCb);
            // 等待所有请求完成
            while (true) {
                if(errCode != Fdt::Err_other){
                    if(errCode == Fdt::Err_success){
                        return true;
                    }else{
                        break;
                    }
                }
                std::this_thread::sleep_for(std::chrono::milliseconds(100));  // 短暂休眠，避免忙等待
            }
        }
        
        

        return false;  // 返回是否有请求成功
    }

    void WlanService::CheckNetworkThread(){
        std::vector<std::string> httpDst = {"http://www.baidu.com", "http://www.google.com"};
        while(m_ExtranetThreadRuning.load()){
            m_ExtranetState.store(CheckNetwork(httpDst));
            std::this_thread::sleep_for(std::chrono::seconds(5));
        }
        m_ExtranetThreadExit.store(true);
    }


    

    void WlanService::NetThreadProc(Fdt::Thread *thread)
    {
        thread->setPriority(Fdt::PRIORITY_NORMAL, Fdt::POLICY_RR);

        int ethCurStat = 1;
        int ethLastStat = mii_diag(LAN_ETH0);
        int wlanCurStat = 1;
        int wlanLastStat = m_wifiConStatus ? 0 : 1;
        bool result = false;
        string gateway;
        vector<RouteItem> routeTable;
        RouteItem routeInfo;
        

        Json::Value apInfo;
        string setNetcard = "";
        bool changeDefaultRoute = true;

        while (thread->running())
        {
            ethCurStat = mii_diag(LAN_ETH0); //0 连接正常
            wlanCurStat = m_wifiConStatus ? 0 : 1; //0 连接正常.这里需要看看设置的值是否正确

            //判断当前默认网关是否通外网
            // if(ethCurStat == 0 && wlanCurStat == 0){
                // if(m_ExtranetThreadExit.load()){
                //     m_ExtranetState.store(false);
                //     m_ExtranetThreadExit.store(false);
                //     m_ExtranetThreadRuning.store(true);
                //     std::thread extnetThread(&WlanService::CheckNetworkThread, this);  
                //     extnetThread.detach();
                // }else{
                //     changeDefaultRoute = !m_ExtranetState.load();
                // } 

                // std::vector<std::string> httpDst = {"http://www.baidu.com", "http://www.google.com"};
                // changeDefaultRoute = !CheckNetwork(httpDst); 
            // }
            // else{
            //     if(!m_ExtranetThreadExit.load()){
            //         m_ExtranetThreadRuning.store(false);
            //         while(!m_ExtranetThreadExit.load()){
            //             std::this_thread::sleep_for(std::chrono::milliseconds(100));
            //         }
            //     }
                
            // }   

            if(ethCurStat != ethLastStat || wlanCurStat != wlanLastStat
               || m_connWiredFlg || m_udhcpcEvent || changeDefaultRoute)
            {

                {
                    lock_guard<recursive_mutex> connLock(m_connMutex);
                    warnf("ethCurStat=%d, wlanCurStat=%d m_connWiredFlg=%d, m_udhcpcEvent=%d , changeDefaultRoute=%d\n",
                                ethCurStat, wlanCurStat,  m_connWiredFlg,  m_udhcpcEvent, changeDefaultRoute);

                    do
                    {
                        ///1. 有线网络插拔的动态分配
                        if(ethCurStat == 0 && ethLastStat != 0)
                        {
                            if(m_dhcpFlg)
                            {
                                //如果有线是动态分配IP,则插拔后重新分配
                                if(!dynamicWiredNetwork())
                                {
                                    errorf("failed dynamicWiredNetwork\n");
                                    //break;
                                }
                            }
                        }

                        ///2. 动态路由配置
                        if(ethCurStat == 0 && wlanCurStat == 0)
                        {
                            if(changeDefaultRoute){
                                //这里要做的操作就是具体选择哪一张网卡作为默认路由了
                                if(setNetcard == LAN_ETH0){
                                    //当前默认路由是无线网卡切换到有线
                                    setNetcard = LAN_WLAN0;
                                }else{
                                    //否则当前默认路由不存在或者是有线网卡切换到无线
                                    setNetcard = LAN_ETH0;
                                }
    
                            }
                        }
                        else if (ethCurStat == 0 && wlanCurStat != 0)
                        {
                            setNetcard = LAN_ETH0;
                        }
                        else if (ethCurStat != 0 && wlanCurStat == 0)
                        {
                            setNetcard = LAN_WLAN0;
                        }
                        else
                        {
                            break;
                        }

                        //2.1 获取当前eth0和wlan0的信息，根据是否同网段，配置普通路由
                        result = setOrdinaryRoute(ethCurStat, wlanCurStat);
                        if(!result)
                        {
                            errorf("setOrdinaryRoute failed\n");
                        }

                        //2.2 设置用户指定网卡的默认路由或当前通路网卡的默认路由
                        result = setDefaultRoute(setNetcard);
                        if(!result)
                        {
                            errorf("SetDefaultRoute failed\n");
                        }

                        
                        if(!IConfigInterface::GetInstance()->Get("APInfo", apInfo)){
                            errorf("Get Config apinfo failed\n");
                            continue;
                        }
                        if(!apInfo.isMember("Retransmit") || !apInfo["Retransmit"].isInt()){
                            errorf("Get Config apinfo failed\n");
                            continue;
                        }
                        //2.3根据不同网卡的网络状况来选择ap转发的网卡
                        if(apInfo["Retransmit"].asInt() == 1)
                        {
                            errorf("Retransmit  wlanTranspond\n");
                            wlanTranspond();
                        }else{
                            errorf("Retransmit  wlanTranspond\n");
                            WlanDelNatForward();
                        }                      

                        break;

                    }while(1);

                    ///3. 标记设置
                    ethLastStat = ethCurStat;
                    wlanLastStat = wlanCurStat;


                    if(m_connWiredFlg)
                    {
                        m_connWiredFlg = false;
                    }
                    if(m_udhcpcEvent){
                        m_udhcpcEvent = false;
                    }
                    if(changeDefaultRoute){
                        changeDefaultRoute = false;
                    }

                }
                // usleep(100*1000);
                warnf("***Route dymic set end......\n");
            }
            sleep(3);

        }

        return;
    }

    bool WlanService::setWiredNetwork(string IP, string Mask, string GateWay, bool Dhcp){
        if(Dhcp){
            //如果是动态分配IP
            if(!dynamicWiredNetwork()){
                errorf("failed dynamicWiredNetwork\n");
                //return false;
            }
        }else{
            // lock_guard<recursive_mutex> connLock(m_connMutex);
            //如果是静态分配IP
            if(!staticWiredNetwork(IP, Mask, GateWay)){
                errorf("failed staticWiredNetwork\n");
                return false;
            }
        }

        //设置DHCP标志位
        char key[8] = {0};
        sprintf(key, "%d", Dhcp);
        if(INI_KeySet(INI_NETWORK_PATH, "network", "dhcp", key)){
            errorf("Fail to write dhcp to net config file!\n");
            return false;
        }

        m_dhcpFlg = Dhcp;

        tracef("ETH0 m_dhcpFlg=%d, m_wiredGateway:%s, m_wiredNetmask=%s, m_wiredDest=%s\n", m_dhcpFlg, m_wiredGateway.c_str(), m_wiredNetmask.c_str(), m_wiredDest.c_str());

        m_connWiredFlg = true;
        return true;
    }

    bool  WlanService::getIpAddress(vector<string> &ips) {
        struct ifaddrs *ifaddr, *ifa;
        char host[NI_MAXHOST];

        if (getifaddrs(&ifaddr) == -1) {
            perror("getifaddrs");
            return false;
        }

        for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
            if (ifa->ifa_addr == NULL)
                continue;

            int family = ifa->ifa_addr->sa_family;
            if (family == AF_INET || family == AF_INET6) {
                int s = getnameinfo(ifa->ifa_addr,
                                    (family == AF_INET) ? sizeof(struct sockaddr_in) :
                                    sizeof(struct sockaddr_in6),
                                    host, NI_MAXHOST,
                                    NULL, 0, NI_NUMERICHOST);
                if(0 == memcmp(LAN_ETH0, ifa->ifa_name, sizeof(ifa->ifa_name))){
                    ips.push_back(host);
                }
            }
        }

        freeifaddrs(ifaddr);
        return true;
    }

    bool WlanService::APIPA(char *IPADDR){
        //调用命令APIPA
        system("zcip eth0 /usr/share/udhcpc/script");
        vector<string> ips;

        for(int inx = 0; inx < 150; inx++){
            ips.clear();
            if(getIpAddress(ips)){
                for(int i = 0; i < ips.size(); i++){
                    if(ips[i].find("169.254.") != string::npos){
                        tracef("succeedzcip:%s\n", ips[i].c_str());
                        memcpy(IPADDR, ips[i].c_str(), ips[i].size());
                        tracef("zcip get ipaddr succeed: %s\n", IPADDR);
                        return true;
                    }
                }
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        errorf("zcip get ipaddr timeout\n");
        return false;
    }

    bool WlanService::dynamicWiredNetwork(){

        //首先需要确保旧的线程关闭
        if(m_EthThreadMark){
            m_EthThreadMark = false;
            while(!m_EthThreadExit){
                usleep(10 * 1000);
            }
        }
        m_EthThreadExit = false;
        m_EthThreadMark = true;
        //开启对应的线程去处理
        m_EthThread = std::thread(&WlanService::dhcpcThreadFuc, this, LAN_ETH0);
        m_EthThread.detach();
        return true;
    }

    bool WlanService::staticWiredNetwork(string IP, string Mask, string GateWay){
        //关闭动态分配机制
        //首先需要确保旧的线程关闭
        if(m_EthThreadMark){
            m_EthThreadMark = false;
            while(!m_EthThreadExit){
                usleep(10 * 1000);
            }
        }
        system("/usr/share/udhcpc/killdhcpc eth0");
        system("killall zcip");
        //先确认三个参数的值。传入参数为空先get再set，传入参数不为空直接使用
        char ipaddrStr[16] = {0};
        char netmaskStr[16] = {0};
        char gatewayStr[16] = {0};
        char destinationStr[16] = {0};

        if(IP.empty() || Mask.empty() || GateWay.empty()){
            return true;
        }


        strcpy(ipaddrStr, IP.c_str());
        strcpy(netmaskStr, Mask.c_str());
        strcpy(gatewayStr, GateWay.c_str());

        //设置IP，Mask和GateWay
        if(NetSetHostIPEx(LAN_ETH0, IP.c_str(), Mask.c_str())){
			errorf("set ipaddr  mask fail \n");
			return false;
		}


        if(NetSetGatewayEx(LAN_ETH0, gatewayStr)){
			errorf("set gateway fail \n");
			return false;
		}

        ipNetmaskToNsid(ipaddrStr, netmaskStr, destinationStr);

        m_wiredGateway = gatewayStr;
        m_wiredNetmask = netmaskStr;
        m_wiredDest = destinationStr;

        return true;
    }


    bool WlanService::getWiredNetwork(Json::Value &table){
        int ret = 0;
        int enable = 1;
        char netmaskStr[16] = {0};
        char ipaddrStr[16] = {0};
        char gatewayStr[16] = {0};
        //获取Dhcp是否开启
        ret = INI_KeyGetInt(INI_NETWORK_PATH, "network", "dhcp", &enable);
        if (ret)
        {
            errorf("Fail to get usb ini key.\n");
            return false;
        }


        if(NetGetHostIPEx(LAN_ETH0,
		   			 ipaddrStr, sizeof(ipaddrStr),
                 			 netmaskStr, sizeof(netmaskStr))){
			errorf("Fail to get ip addr or net mask.\n");
	        return false;
		}

		if(NetGetGatewayEx(LAN_ETH0,gatewayStr, sizeof(gatewayStr))){
			errorf("Fail to get net gateway.\n");
	        return false;
		}

        
        table["IP"] = ipaddrStr;
        table["Mask"] = netmaskStr;
        if(enable == 0){
            table["Dhcp"] = false;
        }else{
            table["Dhcp"] = true;
        }
        table["GateWay"] = gatewayStr;
        return true;
    }


    bool WlanService::getWirelessStatus(string &bssid, string &ssid, unsigned int &channel){
        //检测当前WIFI的连接状态
        WLAN_DEVICE_EXT *deviceInfo = NULL;
        deviceInfo = (WLAN_DEVICE_EXT *)malloc(sizeof(WLAN_DEVICE_EXT));
        if(deviceInfo == NULL){
            errorf("malloc faild!!!");
            channel = 0;
            return true;
        }
        if(WLanConnChk(deviceInfo) == 0){
            bssid = deviceInfo->BSSID;
            ssid  =  deviceInfo->SSID;
            channel = deviceInfo->Channel;
        }else{
            free(deviceInfo);
            return false;
        }

        free(deviceInfo);
        return true;
    }

    bool WlanService::getWirelessStatus(){
        WLAN_DEVICE_EXT *deviceInfo = NULL;
        deviceInfo = (WLAN_DEVICE_EXT *)malloc(sizeof(WLAN_DEVICE_EXT));
        if(deviceInfo == NULL){
            errorf("malloc faild!!!");
            return false;
        }
        if(WLanConnChk(deviceInfo) == 0){
            free(deviceInfo);
            return true;
        }

        free(deviceInfo);
        return false;
    }

    bool WlanService::GetInterfaceWishaddr(char *pInterfaceName, int param, string &addr)
    {
        char ipaddrStr[16] = {0};
        int ipaddr[4] = {0};

        char netmaskStr[16] = {0};
        int netmask[4] = {0};

        int gateway[4] = {0};

        bool wlan0Condition = strcmp(pInterfaceName, LAN_WLAN0) == 0 && m_wifiConStatus;
        bool eth0Condition = strcmp(pInterfaceName, LAN_ETH0) == 0 && mii_diag(LAN_ETH0) == 0;
        bool wlan1Condition = strcmp(pInterfaceName, LAN_WLAN1) == 0;
        if(wlan0Condition || eth0Condition || wlan1Condition){
                if(NetGetHostIPEx(pInterfaceName,
                                        ipaddrStr, sizeof(ipaddrStr),
                                                        netmaskStr, sizeof(netmaskStr))){
                        errorf("Fail to get ip addr or net mask. pInterfaceName\n");
                        return false;
                }
        }else{
            return false;
        }
        //tracef("pInterfaceName:%s, Apaddr before -------------------------> %s\n", pInterfaceName, ipaddrStr);
        sscanf(ipaddrStr, "%d.%d.%d.%d", &ipaddr[0], &ipaddr[1], &ipaddr[2], &ipaddr[3]);
        sscanf(netmaskStr, "%d.%d.%d.%d", &netmask[0], &netmask[1], &netmask[2], &netmask[3]);
        for(int i = 0; i < 4; i++){
            gateway[i] = ipaddr[i] & netmask[i];
        }
        gateway[3] = param;
        memset(ipaddrStr, 0, sizeof(ipaddrStr));
        sprintf(ipaddrStr, "%d.%d.%d.%d", gateway[0], gateway[1], gateway[2], gateway[3]);
        //tracef("pInterfaceName:%s, Apaddr after-------------------------> %s\n", pInterfaceName, ipaddrStr);

        addr = ipaddrStr;
        return true;
    }

    bool WlanService::checkInternetPing(string ip)
    {
        char pingCMD[128]={0};
        char tmpBuf[512]={0};
        FILE *pfile = NULL;

        snprintf(pingCMD, sizeof(pingCMD), PING_CMD, ip.c_str(), TMP_PING_PATH);  /*ping GLOBAL DNS*/
        printf("pingCMD=%s!\n", pingCMD);
        system(pingCMD);
        if((pfile = fopen(TMP_PING_PATH, "rb")) != NULL) {
            fread(tmpBuf, sizeof(tmpBuf), 1, pfile);
            fclose(pfile);
        }
        else {
            printf("open ping file:%s error!\n", TMP_PING_PATH);
        }

        if(strstr(tmpBuf, RECV1ICMPPKT)) {  /*ping success*/
            return true;
        } else {                           /*ping fail*/
            return false;
        }

    }


    bool WlanService::isSameSubnet(void)
    {
        std::string eth0Addr;
        std::string wlan0Addr;
        std::string wlan1Addr;
        GetInterfaceWishaddr(LAN_ETH0, 0, eth0Addr);
        GetInterfaceWishaddr(LAN_WLAN0, 0, wlan0Addr);
        GetInterfaceWishaddr(LAN_WLAN1, 0, wlan1Addr);

        if(wlan1Addr == wlan0Addr
           || wlan1Addr == eth0Addr)
        {
            return true;
        }

        return false;
    }

    std::string WlanService::trimString(const std::string& input)
    {
        std::string result = input;

        // 找到第一个非空白字符的位置
        size_t startPos = result.find_first_not_of(" \t\n\r");

        // 如果 startPos == std::string::npos，说明字符串只包含空白字符，直接返回空字符串
        if (startPos == std::string::npos) {
            return "";
        }

        // 找到最后一个非空白字符的位置
        size_t endPos = result.find_last_not_of(" \t\n\r");

        // 截取子字符串，去除前后空白字符
        result = result.substr(startPos, endPos - startPos + 1);

        return result;
    }

    std::vector<std::string> WlanService::stringSplit(const std::string& str, char delim) {

        std::string trimmed = trimString(str);
        std::stringstream ss(trimmed);
        std::string item;
        std::vector<std::string> elems;

        while (std::getline(ss, item, delim)) {
            if (!item.empty()) {
                elems.push_back(item);
            }
        }
        return elems;
    }


    // 通过IP地址和子网掩码计算网络号，传入正确的ip，正确的netmask，网络号，网络号长度。 成功返回1，失败返回0
    int WlanService::ipNetmaskToNsid(const char* ip, const char* netmask, char* NSID)
    {
        int ip_len = 0;
        int netmask_len = 0;
        int temp_len = 0;
        int temp_len2 = 0;
        int ip_arr[4] = {0};
        int netmask_arr[4] = {0};
        int NSID_arr[4] = {0};
        int i = 0;
        char temp_str[4] = {0};
        char NSID_str[16] = {0};
        char* p_ip = ip;
        char* p_netmask = netmask;

        // 临时指针
        char* temp = NULL;
        // 4次循环依次获取每位ip
        for(i = 0; i < 4; i++)
        {
            // printf("i=%d\n", i);
            ip_len = strlen(p_ip);
            // 获取'.'首次出现的位置
            if(i != 3)
            {
                temp = strchr(p_ip, '.');
                if(NULL == temp)
                {
                    return 0;
                }
            }
            else
            {
                temp = p_ip;
            }
            temp_len = strlen(temp);
            // printf("temp_len=%d\n", temp_len);
            // 计算第一位ip的长度
            if(i != 3)
            {
                temp_len2 = ip_len - temp_len;
            }
            else
            {
                temp_len2 = temp_len;
            }
            // printf("temp_len2=%d\n", temp_len2);
            // 字符串截取
            memset(temp_str, 0, sizeof(temp_str));
            strncpy(temp_str, p_ip, temp_len2);
            // 存入数组
            ip_arr[i] = atoi(temp_str);
            // printf("ip_arr[%d]=%d\n", i, ip_arr[i]);
            // 前3个进行指针偏移
            if(i != 3)
            {
                p_ip += (temp_len2 + 1);
            }
        }

        temp = NULL;
        temp_len = 0;
        temp_len2 = 0;

        // 4次循环依次获取每位netmask
        for(i = 0; i < 4; i++)
        {
            // printf("i=%d\n", i);
            netmask_len = strlen(p_netmask);
            // 获取'.'首次出现的位置
            if(i != 3)
            {
                temp = strchr(p_netmask, '.');
                if(NULL == temp)
                {
                    return 0;
                }
            }
            else
            {
                temp = p_netmask;
            }
            temp_len = strlen(temp);
            // printf("temp_len=%d\n", temp_len);
            // 计算netmask的长度
            if(i != 3)
            {
                temp_len2 = netmask_len - temp_len;
            }
            else
            {
                temp_len2 = temp_len;
            }
            // printf("temp_len2=%d\n", temp_len2);
            // 字符串截取
            memset(temp_str, 0, sizeof(temp_str));
            strncpy(temp_str, p_netmask, temp_len2);
            // 存入数组
            netmask_arr[i] = atoi(temp_str);
            // printf("netmask_arr[%d]=%d\n", i, netmask_arr[i]);
            // 前3个进行指针偏移
            if(i != 3)
            {
                p_netmask += (temp_len2 + 1);
            }
        }

        temp = NULL;

        // 计算各位网络号
        for(i = 0; i < 4; i++)
        {
            NSID_arr[i] = ip_arr[i] & netmask_arr[i];
        }

        // 拼接为完整的网络号
        snprintf(NSID_str, 15, "%d.%d.%d.%d", NSID_arr[0], NSID_arr[1], NSID_arr[2], NSID_arr[3]);

        strncpy(NSID, NSID_str, 16);

        return 1;
    }


    bool WlanService::dhcpcThreadFuc(const string NetCard){
        warnf("dhcpcThreadFuc strt----------------------------\n");
        //首先保证原先的线程退出，之所以支持多次调用是为了切换路由器或者交换机的时候能够及时进行dhcp
        //先关闭之前的网口的udhcpc
        char cmd[128] = {0};
        sprintf(cmd, "/usr/share/udhcpc/killdhcpc %s", NetCard.c_str());
        system(cmd);
        //通信之前首先创建管道
        //监听管道的消息并且设置超时机制
        char pipeName[32] = {0}; // 管道文件路径
        sprintf(pipeName, "/tmp/%s", NetCard.c_str());
        // 使用访问系统调用来检查文件是否存在
        if (access(pipeName, F_OK) == 0) {
            // 文件存在，尝试删除它
            if (!unlink(pipeName) == 0) {
                errorf("error romove pipe file\n");
            }
        } else {
            warnf("file not exist");
        }
        // 创建管道
        if (mkfifo(pipeName, 0777) < 0) {
            std::cerr << "Error creating the named pipe. " <<  strerror(errno) << std::endl;
            if(LAN_ETH0 == NetCard){
                m_EthThreadMark = false;
                m_EthThreadExit = true;
            }else{
                m_WlanThreadMark = false;
                m_WlanThreadExit = true;
            }
            return false;
        }
        // 打开管道
        int pipe_fd = open(pipeName, O_RDWR);
        if (pipe_fd == -1) {
            std::cerr << "Error opening the named pipe." << std::endl;
            if(LAN_ETH0 == NetCard){
                m_EthThreadMark = false;
                m_EthThreadExit = true;
            }else{
                m_WlanThreadMark = false;
                m_WlanThreadExit = true;
            }
            return false;
        }

        memset(cmd, sizeof(cmd), 0);
        // sprintf(cmd, "udhcpc -i %s &", NetCard.c_str());
        sprintf(cmd, "udhcpc -T 1 -t 20 -i %s &", NetCard.c_str());
        system(cmd);

        while((NetCard == LAN_ETH0 && m_EthThreadMark) || (NetCard == LAN_WLAN0 && m_WlanThreadMark)){
            // 使用 select 监听管道，设置超时时间为 10 秒
            fd_set read_fds;
            FD_ZERO(&read_fds);
            FD_SET(pipe_fd, &read_fds);
            struct timeval timeout;
            timeout.tv_sec = 1;
            timeout.tv_usec = 0;

            int selectResult = select(pipe_fd + 1, &read_fds, nullptr, nullptr, &timeout);
            if (selectResult == -1) {
                warnf("Error in select..\n");
                continue;
            } else if (selectResult == 0) {
                //warnf("Select timeout (10 seconds).\n");
                continue;
            } else {
                if (FD_ISSET(pipe_fd, &read_fds)) {
                    // 从管道中读取数据
                    char buffer[1024] = {0};
                    ssize_t bytesRead = read(pipe_fd, buffer, sizeof(buffer));
                    if (bytesRead > 0) {
                        string message = buffer;
                        tracef("-------------------------------message: %s --------\n", buffer);
                        vector<string> members = stringSplit(message, ':');
                        for(int i = 0; i < members.size(); i++){
                            tracef("--------member: %s\n", members[i].c_str());
                        }

                        //解析从管道发送过来的消息
                        if(members.size() < 5){
                            errorf("recvice error message\n");
                            continue;
                        }

                        if(members[0] != NetCard){
                            errorf("using zcip to alloc ip\n");
                            continue;
                        }

                        if(members[1] == "1"){
                            //errorf("members[1] == 1 using zcip to alloc ip\n");
                            //成功则将参数设置到变量让程序去设置IP和路由表
                            char Destination[16] = {0};
                            ipNetmaskToNsid( members[2].c_str(),  members[3].c_str(), Destination);
                            if(NetCard == LAN_ETH0){
                                //分配成功需要设置IP和网关
                                //分配成功需要杀死zcip,避免冲突
                                system("killall zcip");
                                NetSetHostIPEx(LAN_ETH0, members[2].c_str(),  members[3].c_str());
                                NetSetGatewayEx(LAN_ETH0, members[4].c_str());
                                {
                                    // lock_guard<recursive_mutex> connLock(m_connMutex);
                                    m_wiredGateway =  members[4];
                                    m_wiredNetmask =  members[3];
                                    m_wiredDest    =  Destination;

                                }
                            }else{
                                //分配成功需要设置IP和网关
                                NetSetHostIPEx(LAN_WLAN0, members[2].c_str(),  members[3].c_str());
                                NetSetGatewayEx(LAN_WLAN0, members[4].c_str());
                                {
                                    // lock_guard<recursive_mutex> connLock(m_connMutex);
                                    m_wlanGateway = members[4];
                                    m_wlanNetmask = members[3];
                                    m_wlanDest    = Destination;
                                }
                                stopMirrorWeaknetDetect();
                                startMirrorWeaknetDetect(LAN_WLAN0, "", 0, 0, 0);
                            }
                            m_udhcpcEvent = true;

                        }else if(members[1].find("0") != string::npos){
                            //errorf("members[1] == 0 using zcip to alloc ip\n");
                            char ipaddrStr[16] = {0};
                            char netmaskStr[16] = {0};
							if(NetGetHostIPEx(LAN_ETH0,
										ipaddrStr, sizeof(ipaddrStr),
												netmaskStr, sizeof(netmaskStr))){
								errorf("Fail to get ip addr or net mask.\n");
							}

                            if(NetCard == LAN_ETH0 && strstr(ipaddrStr, "169.254") == NULL){
                                char IPADDR[16] = {0};
                                if(APIPA(IPADDR)){
                                    NetSetHostIPEx(LAN_ETH0, IPADDR,  "255.255.0.0");
                                    NetSetGatewayEx(LAN_ETH0, "169.254.0.1");
                                    {
                                        // lock_guard<recursive_mutex> connLock(m_connMutex);
                                        m_wiredGateway = "169.254.0.1";
                                        m_wiredNetmask = "255.255.0.0";
                                        m_wiredDest    =  "169.254.0.0";
                                        m_udhcpcEvent = true;
                                        tracef("succeed end zcip\n");
                                    }
                                }else{
#if 0
                                    bool DhcpFlg = false;
    								bool result = false;
									int status = 0;
									int isDhcp = 0;
									status = INI_KeyGetInt(INI_NETWORK_PATH, "network", "dhcp", &isDhcp);
									if (status)
									{
										errorf("Fail to get usb ini key.\n");
										return -1;
									}

									if (isDhcp)
									{
										DhcpFlg = true;
									}
									else
									{
										DhcpFlg = false;
									}
									result = WlanService::instance()->setWiredNetwork("", "", "", DhcpFlg);
									if (!result)
									{
										errorf("Fail to setWiredNetwork.\n");
									}
#endif
                                    errorf("faild to zcip\n");
                                }
                            }
                        }
                    } else {
                        std::cerr << "Error reading from pipe." << std::endl;
                    }
                }
            }
        }

        // 关闭管道和删除管道文件
        close(pipe_fd);
        unlink(pipeName);
        remove(pipeName);
        if(LAN_ETH0 == NetCard){
            m_EthThreadExit = true;
        }else{
            m_WlanThreadExit = true;
        }

        sprintf(cmd, "/usr/share/udhcpc/killdhcpc %s", NetCard.c_str());
        system(cmd);
        return true;
    }


    int WlanService::getWifiApSignalDb(string ssid){
        map<string, WLAN_DEVICE_EXT>::iterator apIt = m_bssidInfo.find(ssid);
        if(apIt == m_bssidInfo.end()){
            errorf("cannot to get bssid by ssid:%s\n", ssid.c_str());
            return 0;
        }else{
            return (int)apIt->second.LinkQuality;
        }
        return 0;
    }


    string WlanService::getWlanGateway(){
        return  m_wlanGateway;
    }

    bool WlanService::getApChannel(string filename, int &channel){
        // 尝试打开文件
        std::ifstream inputFile(filename);

        if (!inputFile.is_open()) {
            std::cerr << "无法打开文件: " << filename << std::endl;
            return false;
        }

        std::string line;
        while (std::getline(inputFile, line)) {
            // 在控制台中打印每一行
            std::cout << line << std::endl;
            size_t pos = line.find("channel=");
            size_t len = strlen("channel=");
            if(pos != string::npos){
                string channels = line.substr(pos + len, line.size() - len);
                channel = stoi(channels);
                break;
            }
        }

        inputFile.close(); // 关闭文件

        return true;
    }

    bool WlanService::setWlanStaChannel(int channel){
        m_WlanStaChannel = channel;
        return true;
    }

    bool WlanService::setTailMatch(bool value){
        m_tailMatch = value;
        return true;
    }

    bool WlanService::getApInfo(string& apInfo)
    {
        apInfo = m_apInfo;
        return true;
    }

    bool WlanService::getApInfo(string& apName, string& apPassword)
    {
        apName = m_apName;
        apPassword = m_apPassword;
        return true;
    }
    
	bool WlanService::pingUtil(std::string netCard, std::string ip){
		char cmd[1024] = {0};
		char buff[1024] = {0};
		char *pStr;
		int num = 0;
		sprintf(cmd, "ping -I %s -c 2 -W 1 %s", netCard.c_str(), ip.c_str());
		tracef("cmd: %s\n", cmd);
		FILE *fp = popen(cmd, "r");
		if (!fp)
		{
			errorf("Fail to popen.\n");
		}else{
			fread(buff, 1, 1024, fp);
			pStr = strstr(buff, "packets transmitted");
			if (pStr)
			{
				tracef("pStr:%s\n", pStr);
				sscanf(pStr, "packets transmitted, %d packets received", &num);
			}
			if (num > 0)
			{
				tracef("ping succeed\n");
                pclose(fp);
				return true;
			}
			else
			{
				tracef("ping faild\n");
                pclose(fp);
				return false;
			}
			pclose(fp);
		}
		return false;
	}

    std::string WlanService::MirrorNetcard(){
        //判断是否是tail投屏，不是就不做处理
        std::string clientAddr = getMirrorIp();
        if(clientAddr.empty()){
            return "";
        }
        
        std::vector<std::string> netCards = {LAN_WLAN1, LAN_WLAN0, LAN_ETH0};
        char ipaddrStr[16] = {0};
        char netmaskStr[16] = {0};
        int netmask[4] = {0};
        int clientIpaddr[4] = {0};
        std::string clientGateWay;
        string targetIp;

        sscanf(clientAddr.c_str(), "%d.%d.%d.%d", &clientIpaddr[0], &clientIpaddr[1], &clientIpaddr[2], &clientIpaddr[3]);
        for(int i = 0; i < netCards.size() ; i++){
            clientGateWay = "";
            targetIp = "";
            memset(ipaddrStr, 0, sizeof(ipaddrStr));
            memset(netmaskStr, 0, sizeof(netmaskStr));
            memset(netmask, 0, sizeof(netmask));

            WlanService::instance()->GetInterfaceWishaddr(netCards[i].c_str(), 0, targetIp);

            if(NetGetHostIPEx(netCards[i].c_str(),
                                        ipaddrStr, sizeof(ipaddrStr),
                                                        netmaskStr, sizeof(netmaskStr)) == 0){
                sscanf(netmaskStr, "%d.%d.%d.%d", &netmask[0], &netmask[1], &netmask[2], &netmask[3]);
                for(int j = 0; j < 4; j++){
                    clientGateWay += std::to_string(netmask[j] & clientIpaddr[j]);
                    if(j != 3){
                        clientGateWay += ".";
                    }
                }
                // errorf("clientGateWay: %s,   targetIp:%s\n", clientGateWay.c_str(), targetIp.c_str());
                if(clientGateWay == targetIp){
                    return std::string(netCards[i].c_str());
                }
            }
        }
        
        return "";
    }

    std::string  WlanService::getMirrorIp(){
        std::lock_guard<std::mutex> lock(m_mirrorIpLock);
        return m_mirrorIp;
    }

    bool  WlanService::setMirrorIp(std::string ip){
        std::lock_guard<std::mutex> lock(m_mirrorIpLock);
        m_mirrorIp = ip;
        return true;
    }


    bool WlanService::startMirrorWeaknetDetect(std::string netCard, std::string clientAddr, int maxTimeout, int avgPacketnum, int avgMaxTimeout) {
        return true;
        std::lock_guard<std::mutex> lock(m_weakDetechLock);
        m_weakNetRunning.store(true);
        m_weakNetThread.store(true);
        //启动线程检测网络质量
        std::thread detechThread(&WlanService::MirrorWeaknetDetectThread, this, netCard, clientAddr, maxTimeout, avgPacketnum,avgMaxTimeout);  
        detechThread.detach();
        return true;
    }

    bool WlanService::MirrorWeaknetDetectThread(std::string netCard, std::string clientAddr, int maxTimeout, int avgPacketnum, int avgMaxTimeout){
        FILE *fp;
        char killPingcmd[1024];
        do{
            if(!m_wifiConStatus){
                break;
            }            
           
            //启用进程判断网络质量
            char cmd[1024];
            char buff[1024];
            
            int totalPacket = 0;
            std::vector<int> nearTime(avgPacketnum, 50);
            

            snprintf(cmd, sizeof(cmd), "ping -I %s %s", netCard.c_str(), m_wlanGateway.c_str());
            
            snprintf(killPingcmd, sizeof(killPingcmd), "kill $(ps aux | grep \"%s\" | grep -v grep | awk '{print $1}')", cmd);
            fp = popen(cmd, "r");
            if (!fp) {
                // Failed to execute ping command
                break;
            }

             // 使用select监视ping命令的输出
            fd_set rfds;
            struct timeval tv;
            int retval;
            // 清空文件描述符集合
            FD_ZERO(&rfds);
            // 将ping命令的输出文件描述符加入到集合中
            FD_SET(fileno(fp), &rfds);
            int lossPacketNum = 0;
         
             
            //通过管道读取进程输出，这里需要考虑退出情况，网络超时，ping包的时间间隔超过单个包超过某个值或者连续连个包超过某个值
            //考虑本进程退出的情况，
            while (m_weakNetRunning.load()) {
                // 设置select超时时间为1秒
                tv.tv_sec = 1;
                tv.tv_usec = 1000 * 500;
                retval = select(fileno(fp) + 1, &rfds, NULL, NULL, &tv);
                if (retval < 0) {
                    errorf("Error in select() retval:%d\n", retval);
                    break;
                } else if (retval == 0) {
                    system(killPingcmd);
                    pclose(fp);
                    fp = popen(cmd, "r");
                    if (!fp) {
                        // Failed to execute ping command
                        break;
                    }
                    FD_ZERO(&rfds);
                    FD_SET(fileno(fp), &rfds);
                    // 超时
                    if(lossPacketNum < 3){
                        lossPacketNum++;
                    }
                    if(lossPacketNum == 2){
                        GuiDisplay::Instance()->DisplayWarnWifi();
                    }
                    errorf("Timeout occurred.  retval: %d\n", retval);

                }else{
                    // 文件描述符上有数据可读
                    if (FD_ISSET(fileno(fp), &rfds)) {
                        // 读取ping命令的输出
                        memset(buff, 0, sizeof(buff));
                        if (fgets(buff, sizeof(buff), fp) == NULL) {
                            break;
                        }
                    }
                }
                


            #if 0
                // Check for "bytes from" in output, indicating successful ping reply
                if (strstr(buff, "bytes from") != NULL) {
                    //获取本次延时
                    int time_sec;
                    char *pos = strstr(buff, "time=");
                    if(sscanf(pos + 5, "%d ms", &time_sec) != 1){
                        errorf("cannot get a ping time\n");
                        continue;
                    }
                    totalPacket++;
                    //这里需要先判断是否超过最大延时
                    if(time_sec >= maxTimeout){
                        break;
                    }
                    //这里需要统计最近多次包的平均延时，先初始化一个值为默认值的数组，根据接收到的包的序号取余存放然后计算平均值
                    nearTime[totalPacket % avgPacketnum] = time_sec;
                    int sum = 0;
                    for(int num : nearTime){
                        sum += num;
                    }
                    if(sum / avgPacketnum > avgMaxTimeout){
                        break;
                    }
                } else if (strstr(buff, "timeout")) {
                    //超时直接断开网络
                    break;
                }
            #endif
            }
        }while(false);
       
        if(fp){    
            system(killPingcmd);
            pclose(fp);
        }
        m_weakNetRunning.store(false);
        m_weakNetThread.store(false);
        return true;  
    }

    bool WlanService::stopMirrorWeaknetDetect(){
        return true;
        std::lock_guard<std::mutex> lock(m_weakDetechLock);
        warnf("stopMirrorWeaknetDetect ---------------------\n");
        if(m_weakNetThread.load()){
            m_weakNetRunning.store(false);
            while(m_weakNetThread.load()){
                usleep(1000 * 50);
            }
        }
        return true;
    }

}

// #include <net/if.h>
// #include <sys/ioctl.h>

// bool pingGateway(const string& interfaceName, const string& gatewayIP, int& delay) {
//     int sockfd;
//     struct sockaddr_in gatewayAddr;
//     struct ifreq ifr;

//     // Create a socket
//     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
//     if (sockfd < 0) {
//         cerr << "Failed to create socket" << endl;
//         return false;
//     }

//     // Set up the gateway address
//     gatewayAddr.sin_family = AF_INET;
//     inet_pton(AF_INET, gatewayIP.c_str(), &gatewayAddr.sin_addr);

//     // Set up the interface
//     strncpy(ifr.ifr_name, interfaceName.c_str(), IFNAMSIZ);
//     if (ioctl(sockfd, SIOCGIFINDEX, &ifr) < 0) {
//         cerr << "Failed to get interface index" << endl;
//         close(sockfd);
//         return false;
//     }

//     // Set the socket option to bind to the interface
//     if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) {
//         cerr << "Failed to bind to interface" << endl;
//         close(sockfd);
//         return false;
//     }

//     // Ping the gateway
//     char buffer[64];
//     struct timespec start, end;
//     clock_gettime(CLOCK_REALTIME, &start);
//     sendto(sockfd, buffer, 64, 0, (struct sockaddr*)&gatewayAddr, sizeof(gatewayAddr));
//     clock_gettime(CLOCK_REALTIME, &end);
//     delay = (end.tv_nsec - start.tv_nsec) / 1000000; // Convert to milliseconds

//     close(sockfd);
//     return true;
// }
